home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pcmagazi / 1992 / 16 / winclip.c < prev    next >
C/C++ Source or Header  |  1992-06-03  |  5KB  |  240 lines

  1. /* 
  2. WINCLIP.C -- DOS access to Windows Clipboard (Enhanced mode)
  3.  
  4. Copyright (c) 1992 Ziff Davis Communications
  5. PC Magazine * Andrew Schulman (June 1992)
  6. */
  7.  
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <malloc.h>
  11. #include <signal.h>
  12. #include <dos.h>
  13. #include "winclip.h"
  14.  
  15. static int winoldap = 0;
  16. static int clip_open = 0;
  17.  
  18. static int clip_init(void);
  19.  
  20. /* higher-level functions */
  21.  
  22. int WindowsClipboard(void)
  23. {
  24.     return (IdentifyWinOldApVersion() != 0);
  25. }
  26.     
  27. /* NOTE: len should include NULL-termination byte, 
  28.    which is required */
  29. int PutClipStrLen(char *s, unsigned len)
  30. {
  31.     if (! winoldap)
  32.         if (! clip_init())
  33.             return 0;
  34.         
  35.     if (! OpenClipboard())
  36.         return 0;
  37.     if (! EmptyClipboard())
  38.     {
  39.         CloseClipboard();
  40.         return 0;               /* couldn't empty */
  41.     }
  42.     if (CompactClipboard(len) < len)
  43.     {
  44.         CloseClipboard();
  45.         return 0;               /* couldn't compact */
  46.     }
  47.     if (! SetClipboardData(CF_TEXT, s, len))
  48.     {
  49.         CloseClipboard();
  50.         return 0;               /* couldn't set */
  51.     }
  52.     CloseClipboard();
  53.     Yield();
  54.     return 1;
  55. }
  56.  
  57. int PutClipString(char *str)
  58. {
  59.     return PutClipStrLen(str, strlen(str)+1);
  60. }
  61.  
  62. char *GetClipString(void)
  63. {
  64.     unsigned long len;
  65.     char *s;
  66.     
  67.     if (! winoldap)
  68.         if (! clip_init())
  69.             return (char *) 0;
  70.  
  71.     if (! OpenClipboard())
  72.         return (char *) 0;
  73.     /* MUST do OpenClipboard BEFORE GetClipboardDataSize */
  74.     if ((len = GetClipboardDataSize(CF_TEXT)) == 0)
  75.     {
  76.         CloseClipboard();
  77.         return (char *) 0;      /* nothing there */
  78.     }
  79.     if (len > (0xFFFFU - 16))
  80.     {
  81.         CloseClipboard();
  82.         return (char *) 0;      /* too big */
  83.     }
  84.     if ((s = (char *) calloc((unsigned) len+1, 1)) == NULL)
  85.     {
  86.         CloseClipboard();
  87.         return (char *) 0;      /* insufficient memory */
  88.     }
  89.     if (! GetClipboardData(CF_TEXT, s))
  90.     {
  91.         CloseClipboard();
  92.         return (char *) 0;      /* couldn't get it */
  93.     }
  94.     CloseClipboard();
  95.     Yield();
  96.     return s;
  97. }
  98.  
  99. void FreeClipString(char *s)
  100. {
  101.     free(s);
  102. }
  103.  
  104. /*********************************************************/
  105.  
  106. /* lower-level functions */
  107.  
  108. void sigint_handler(int sig)
  109. {
  110.     if (clip_open != 0)
  111.         CloseClipboard();
  112.     exit(1);
  113. }
  114.  
  115. void exit_func(void)
  116. {
  117.     if (clip_open != 0)
  118.         CloseClipboard();
  119. }
  120.  
  121. static int clip_init(void)
  122. {
  123.     if (winoldap)
  124.         return 1;   /* already did init */
  125.             
  126.     if (! (winoldap = IdentifyWinOldApVersion()))
  127.         return 0;
  128.     
  129.     /* install handlers so that we never exit holding
  130.        the clipboard open */
  131.     atexit(exit_func);              /* at-exit handler */
  132.     signal(SIGINT, sigint_handler); /* Ctrl-C handler */
  133.     return 1;
  134. }
  135.  
  136. unsigned long CompactClipboard(unsigned long len)
  137. {
  138.     _asm push si
  139.     _asm mov ax, 1709h
  140.     _asm mov si, word ptr len+2
  141.     _asm mov cx, word ptr len
  142.     _asm int 2fh
  143.     _asm pop si
  144.     /* return value in DX:AX (size) */
  145. }
  146.  
  147. unsigned CloseClipboard(void)
  148. {
  149.     unsigned retval;
  150.     _asm mov ax, 1708h
  151.     _asm int 2fh
  152.     _asm mov retval, ax
  153.     if (retval) clip_open--;
  154.     Yield();    /* seems like a good place to put it */
  155.     return retval;
  156. }
  157.  
  158. unsigned EmptyClipboard(void)
  159. {
  160.     _asm mov ax, 1702h
  161.     _asm int 2fh
  162.     /* return value in AX (0 if failure) */
  163. }
  164.  
  165. unsigned char far *GetClipboardData(CF_FORMAT format, 
  166.     unsigned char far *buf)
  167. {
  168.     unsigned retval;
  169.     _asm mov ax, 1705h
  170.     _asm mov dx, format
  171.     _asm les bx, buf
  172.     _asm int 2fh
  173.     _asm mov retval, ax
  174.     return retval? buf : (unsigned char far *) 0;
  175. }
  176.  
  177. unsigned long GetClipboardDataSize(CF_FORMAT format)
  178. {
  179.     _asm mov ax, 1704h
  180.     _asm mov dx, format
  181.     _asm int 2fh
  182.     /* return value in DX:AX (size) */
  183. }
  184.  
  185. unsigned GetDeviceCaps(unsigned index)
  186. {
  187.     _asm mov ax, 170Ah
  188.     _asm mov dx, index
  189.     _asm int 2fh
  190.     /* return value in AX (device capability) */
  191. }
  192.  
  193. unsigned IdentifyWinOldApVersion(void)
  194. {
  195.     unsigned vers;
  196.     _asm mov ax, 1700h
  197.     _asm int 2fh
  198.     _asm mov vers, ax
  199.     /* if AX still 1700h, then WINOLDAP not present */
  200.     return (vers == 0x1700) ? 0 : vers;
  201. }
  202.  
  203. unsigned OpenClipboard(void)
  204. {
  205.     unsigned retval;
  206.     _asm mov ax, 1701h
  207.     _asm int 2fh
  208.     _asm mov retval, ax
  209.     if (retval) clip_open++;
  210.     return retval;
  211. }
  212.  
  213. unsigned SetClipboardData(CF_FORMAT format, 
  214.     unsigned char far *buf, unsigned long len)
  215. {
  216.     _asm push si            /* save SI; compiler may use it */
  217.     _asm mov ax, 1703h      /* SetClipboardData */
  218.     _asm mov dx, format     /* CF_ format */
  219.     _asm les bx, buf        /* far pointer to buffer */
  220.     _asm mov si, word ptr len+2     /* HIWORD of length */
  221.     _asm mov cx, word ptr len       /* LOWORD of length */
  222.     _asm int 2fh            /* call WINOLDAP API */
  223.     _asm pop si             /* restore saved SI */
  224.     /* return value in AX (0 if failure) */
  225. }
  226.  
  227. /* Problem:  as soon as DOS box makes even one Yield, it
  228.    barely runs in the background anymore (especially in 3.1) */
  229. void Yield(void)
  230. {
  231. #if 1
  232.     _asm int 28h
  233.     _asm int 28h
  234.     _asm int 28h
  235. #else
  236.     _asm mov ax, 1680h
  237.     _asm int 2fh
  238. #endif      
  239. }
  240.